#include"udp.h"


int Udp_Inti(void)
{
     //Make a udp-socket 
    int fd_socket= socket(AF_INET,SOCK_DGRAM, 0);
    if(-1==fd_socket)
    {
        perror("socket error");
        return -1;
    }

    struct sockaddr_in serveraddrmsg={
        .sin_family=AF_INET,
        .sin_port=htons(PROT),
        .sin_addr.s_addr=htonl(INADDR_ANY)  
    };

    socklen_t addrlen=sizeof(struct sockaddr_in);
    int bind_ret=bind(fd_socket, (const struct sockaddr *)&serveraddrmsg,addrlen);
    if(bind_ret==-1)
    {
        perror("bind error");
        return -1;
    }

    return fd_socket;

}

int Send_Onlinelist(c_list head_connected,int fd_socket,int port,char*ip)
{
   
    char *msg_send=calloc(MSG_LEN,1);

    struct sockaddr_in dest={
                .sin_family=AF_INET,
                .sin_port=htons(port),
                // .sin_addr.s_addr= htonl(INADDR_ANY),
                .sin_addr.s_addr=inet_addr(ip)
                                };

      for(c_list tmp=head_connected->Next;tmp!=NULL;tmp=tmp->Next)
        {
            bzero(msg_send,MSG_LEN);
            snprintf(msg_send,MSG_LEN,"ONLINE:Ip[%s] Port[%d]",tmp->ipv4,tmp->port);

                int sendbyte=sendto(fd_socket,msg_send,strlen(msg_send), 0,
                            (const struct sockaddr *)&dest, sizeof(dest));
                if(-1==sendbyte)
                {
                    perror("sendto error");
                    return -1;
                }
                else
                {
                    // printf("send message successed,sendbyte=%d\n",sendbyte);
                }

        }

        char * client_msg=calloc(MSG_LEN,1);        
        snprintf(client_msg,MSG_LEN,"Your Ip[%s] --Port[%d]",ip,port);

        int sendbyte2=sendto(fd_socket,client_msg,strlen(msg_send), 0,
                    (const struct sockaddr *)&dest, sizeof(dest));
        if(-1==sendbyte2)
        {
            perror("sendto error");
            return -1;
        }
        else
        {
            // printf("send message successed,sendbyte=%d",sendbyte2);
        }
                

        return 0;
}




int Send_Reply(char*msg,int fd_socket,int port,char*ip)
{

    char *msg_send=calloc(MSG_LEN,1);

    struct sockaddr_in dest={
                .sin_family=AF_INET,
                .sin_port=htons(port),
                // .sin_addr.s_addr= htonl(INADDR_ANY),
                .sin_addr.s_addr=inet_addr(ip)
                                };
    bzero(msg_send,MSG_LEN);
    strncpy(msg_send,msg,MSG_LEN);
    int sendbyte=sendto(fd_socket,msg_send,strlen(msg_send), 0,
                                (const struct sockaddr *)&dest, sizeof(dest));

         if(-1==sendbyte)
        {
            perror("sendto error");
            return -1;
        }
        else
        {
            // printf("send message successed,sendbyte=%d",sendbyte);
        }
                

        return 0;

}

int Asking_chat(c_list head_connected,c_list head_chating,int fd_socket,char *msg_recv,char *srcip,int srcport)
{
            char c;
            char ipaddr[64];
            int port;
            bzero(ipaddr,64);
            sscanf(msg_recv,"%c %s %d",&c,ipaddr,&port);
            printf("client IP[%s] port[%d] asking for a chat to ---client IP[%s]-[%d]\n",
                                srcip,srcport,ipaddr,port);
            if(find4list(head_connected,port,ipaddr))
            {
                printf("target is in list\n");
                int ret_reply=Send_Reply("target is in list,asking for a chat",fd_socket,srcport,srcip);

                if(-1==ret_reply)
                {
                    printf("send reply failed\n");
                    return -1;
                }

                char msg[MSG_LEN];
                bzero(msg,MSG_LEN);
                snprintf(msg,MSG_LEN,"client IP[%s] port[%d] asking for a chat,'y'for accept 'n'for refuse",
                                                    srcip,srcport);
                

                int ret_ask=Send_Reply(msg,fd_socket,port,ipaddr);
                 if(-1==ret_ask)
                {
                    printf("send reply failed\n");
                    return -1;
                }

                struct sockaddr_in cilentaddrmsg;
                socklen_t addrlen=sizeof(struct sockaddr_in);
                char *msg_recv=calloc(MSG_LEN,1);
                bzero(msg_recv,MSG_LEN);
                bzero(&cilentaddrmsg,addrlen);
                ssize_t ret_recvfrom= recvfrom(fd_socket, msg_recv, MSG_LEN,0,
                                                (struct sockaddr *)&cilentaddrmsg, &addrlen);
                    if(-1==ret_recvfrom)
                    {
                        perror("recvfrom error");
                    }
                if(!strcmp(msg_recv,"y\n"))
                {
                
                    int Ret_val=add2_Chatinglist(head_connected,head_chating,srcport,srcip,port,ipaddr);
                
                    if(Ret_val==-1)
                    {
                        printf("add to chating list failed\n");
                    }
                    else if(Ret_val==0)
                    {
                       printf("Already exist in chating list\n");
                    }
                    else
                    {
                        printf("add to chating list successed\n");

                    int ret_reply=Send_Reply("connect to target client successed,you can chat to him now!!\n",fd_socket,srcport,srcip);
                         if(-1==ret_reply)
                    {
                        perror("Send_Reply error");
                    }

                      int ret_reply2=Send_Reply("connect to target client successed,you can chat to him now!!\n",fd_socket,port,ipaddr);
                         if(-1==ret_reply2)
                    {
                        perror("Send_Reply error");
                    }

                    }
                }
                if(!strcmp(msg_recv,"n\n"))
                {
                    printf("target client rufuse to chat\n");
                    int ret_reply=Send_Reply("target client rufuse to chat",fd_socket,srcport,srcip);

                    if(-1==ret_reply)
                    {
                        printf("send reply failed\n");
                        return -1;
                    }

                }

                
            }
            else
            {
                printf("target not found\n");
                int ret_reply=Send_Reply("target not found",fd_socket,srcport,srcip);

                if(-1==ret_reply)
                {
                    printf("send reply failed\n");
                    return -1;
                }

            }
}

int Udp_Dataswap(c_list head_chating,int fd_socket,char * msg_recv,int srcport,char * srcip)
{
      c_list pos=find4_chatinglist(head_chating,srcport,srcip,0,NULL);
            if(pos!=NULL)
            {
                if(srcport==pos->Client1->port&&!strcmp(srcip,pos->Client1->ipv4))

                {
                    printf("Got msg from ip[%s] prot[%d]  to  ip[%s] prot[%d]",
                                        srcip,srcport,pos->Client2->ipv4,pos->Client2->port);

                    int ret_reply=Send_Reply(msg_recv,fd_socket,
                                                         pos->Client2->port,pos->Client2->ipv4);
                    
                    bzero(msg_recv,MSG_LEN);
                    if(-1==ret_reply)
                    {
                        printf("send reply failed\n");
                    }
                   return 0;
                }
                else if(srcport==pos->Client2->port&&
                                        !strcmp(srcip,pos->Client2->ipv4))
                {
                    printf("Got msg from ip[%s] prot[%d]  to  ip[%s] prot[%d]\n",
                                        srcip,srcport,
                                                                        pos->Client1->ipv4,pos->Client1->port);

                    int ret_reply=Send_Reply(msg_recv,fd_socket,
                                                         pos->Client1->port,pos->Client1->ipv4);

                    bzero(msg_recv,MSG_LEN);
                    if(-1==ret_reply)
                    {
                        printf("send reply failed\n");
                    }

                   return 0;
                }
            }
            else
            {
                printf("This client is not found in chating list\n");
                return -1;

            }

}



int Send_Broadcast(c_list head_connected,int fd_socket,char *msg_recv)
{

    char c;
    char cmd[32];
    char broadcast_msg[512];
    char broadcastsend_msg[512];
    bzero(broadcast_msg,512);
    bzero(cmd,32);

    sscanf(msg_recv,"%c %s %s",&c,cmd,broadcast_msg);

    snprintf(broadcastsend_msg,525,"Broadcast:%s\n",broadcast_msg);


    for(c_list tmp=head_connected->Next;tmp!=NULL;tmp=tmp->Next)
    {
        // printf("ip:%s  prot:%d  fd:%d  state:online\n",tmp->ipv4,tmp->port,tmp->fd);
    int ret_reply=Send_Reply(broadcastsend_msg,fd_socket,tmp->port,tmp->ipv4);

        bzero(msg_recv,MSG_LEN);
        if(-1==ret_reply)
        {
            printf("send reply failed\n");
            return-1;
        }

    }

    return 0;

}


int group_add(c_list head_group,char* msg_recv,char*srcip,int srcport)
{

    char cmd[32];
    int groupnum;
    sscanf(msg_recv,"%s %d",cmd,&groupnum);

   
   c_list tmp=find4_grouplist(head_group,groupnum);
   if(tmp==NULL)
   {   
        int ret_val=add2_grouplist(head_group,groupnum);
        if(-1==ret_val)
        {
            printf("add to grouplist failed\n");
            return -1;
        }

   }
  
        c_list tem=find4_grouplist(head_group,groupnum);
 
       c_list pos=find4_groupmember(tem,srcport,srcip);
       if(NULL==pos)
       { printf("--%s--%d\n",__FUNCTION__,__LINE__);
           int retValue= add2_groupmember(tem,srcport,srcip);
           if(-1==retValue)
           {
            printf("add groupmember failed\n");
            return -1;
           }
           return 0;
       }

}

int Send2_group(int fd_socket,char *msg_recv,c_list head_group)
{
    char cmd[32];
    int groupnum;
    char msg[512];
    char group_msg[530];
    bzero(cmd,32);
    bzero(msg,512);
    bzero(group_msg,530);
    sscanf(msg_recv,"%s %d %s",cmd,&groupnum,msg);
    snprintf(group_msg,530,"group[%d] msg:%s",groupnum,msg);

    c_list tmp=find4_grouplist(head_group,groupnum);

    for(c_list pos=tmp->Client1;pos!=NULL;pos=pos->Client1)
    {
       int ret_reply=Send_Reply(group_msg,fd_socket,pos->port,pos->ipv4);
       if(-1==ret_reply)
       {
           printf("send group message failed\n ");
           return -1;
       }
    }
    return 0;

}




int Udp_detialswap(c_list head_chating,int fd_socket,char * msg_recv,int srcport,char * srcip)
{
      c_list pos=find4_chatinglist(head_chating,srcport,srcip,0,NULL);
            if(pos!=NULL)
            {
                if(srcport==pos->Client1->port&&!strcmp(srcip,pos->Client1->ipv4))

                {
                    printf(" ip[%s] prot[%d] wants to send file to  ip[%s] prot[%d]",
                                        srcip,srcport,pos->Client2->ipv4,pos->Client2->port);

                    char srcdetail[256];
                    bzero(srcdetail,256);
                    snprintf(srcdetail,256,"@ %s %d",srcip,srcport);
                    int ret_reply=Send_Reply(srcdetail,fd_socket,
                                                         pos->Client2->port,pos->Client2->ipv4);
                    
                    bzero(msg_recv,MSG_LEN);
                    if(-1==ret_reply)
                    {
                        printf("send reply failed\n");
                    }
                   return 0;
                }
                else if(srcport==pos->Client2->port&&
                                        !strcmp(srcip,pos->Client2->ipv4))
                {
                    printf("Got msg from ip[%s] prot[%d]  to  ip[%s] prot[%d]\n",
                                        srcip,srcport,pos->Client1->ipv4,pos->Client1->port);

                    char srcdetail[256];
                    bzero(srcdetail,256);
                    snprintf(srcdetail,256,"@ %s %d",srcip,srcport);

                    int ret_reply=Send_Reply(srcdetail,fd_socket,
                                                         pos->Client1->port,pos->Client1->ipv4);

                    bzero(msg_recv,MSG_LEN);
                    if(-1==ret_reply)
                    {
                        printf("send reply failed\n");
                    }

                   return 0;
                }
            }
            else
            {
                printf("This client is not found in chating list\n");
                return -1;

            }

}